﻿using ApiIOCService.Interface;
using Microsoft.Practices.Unity;
using Model;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Mvc;

namespace TestApi.Controllers
{
    public class HomeController : Controller
    {
        [Dependency]
        public ICouponService CouponService { get; set; }

        [Dependency]
        public IApplicationLogService ApplicationLogService { get; set; }

        [HttpGet]
        public ActionResult GetIP(string url)
        {
            if (string.IsNullOrEmpty(url)) return Content("127.0.0.1");
            try
            {
                url = HttpUtility.UrlDecode(url);
                Uri uri = new Uri(url);
                IPAddress[] aryIP = Dns.GetHostAddresses(uri.Host);
                string result = aryIP[0].ToString();
                return Content(result);
            }
            catch (Exception ex)
            {
                return Content("127.0.0.1");
            }
        }

        public ActionResult Index(int batchId = 0)
        {
            CouponService.GetCouponBatch(batchId);

            System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
            sw.Start();
            System.Threading.Tasks.Task<Tuple<List<int>, long>> task = new System.Threading.Tasks.Task<Tuple<List<int>, long>>(() =>
            {
                return SysTaskTest();
            });
            task.Start();
            sw.Stop();
            return Content(string.Format("执行Task，耗时：{0}毫秒", sw.ElapsedMilliseconds));
        }

        Tuple<List<int>, long> SysTaskTest()
        {
            ApplicationLogService.Info("调用SysTaskTest");
            List<int> list = new List<int>();
            for (int i = 0; i < 10; i++)
            {
                list.Add(i);
            }
            System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch();
            sw.Start();

            var ls = (from p in list.AsParallel().WithDegreeOfParallelism(10)
                      select SysTaskTest(p)).Where(x => x < 5).ToList();

            //List<int> ls = new List<int>();
            //System.Threading.Tasks.Parallel.ForEach(list, o =>
            //{
            //    var i = SysTaskTest(o);
            //    if (i < 5)
            //        ls.Add(i);
            //});

            sw.Stop();

            ApplicationLogService.Info(string.Format("调用SysTaskTest 耗时[{1}毫秒] 结果{0}", Newtonsoft.Json.JsonConvert.SerializeObject(ls), sw.ElapsedMilliseconds));

            return new Tuple<List<int>, long>(ls, sw.ElapsedMilliseconds);
        }

        int SysTaskTest(int i)
        {
            System.Threading.Thread.Sleep(500);
            return new Random().Next(0, 10);
        }


        [HttpGet]
        public JsonResult GetGenerate()
        {
            GeneratorResponse res = new GeneratorResponse();
            Generate(res);
            return Json(new JsonBaseModel<GeneratorResponse> { Code = 0, Result = res }, JsonRequestBehavior.AllowGet);
        }

        static string _serverNumber;
        static CurrentNumberStatus _numberStatus;
        static bool _serviceUseable = true;
        static string _latestError;

        /// <summary>
        /// 静态函完成启动过程初始化
        /// </summary>
        static HomeController()
        {
            Exception exflag = null;
            try
            {
                //服务器编号，如果服务器ip有多个。。。。。。用配置了
                _serverNumber = GetIPAddress();

                if (_serverNumber == null)
                {
                    throw new Exception(_latestError);
                }

                try
                {
                    if (true)
                    {
                        //第一次启动
                        if (_numberStatus == null)
                        {
                            _numberStatus = new CurrentNumberStatus();
                            _numberStatus.LatestMaxNumber = 0;
                        }
                        else
                        {
                            _numberStatus.LatestMaxNumber = Math.Max(_numberStatus.LatestMaxNumber, 0);
                        }

                        _numberStatus.Date = DateTime.Now.ToString("yyMMddHH");
                    }
                    else
                    {
                        //db数据状态有误，多半是程序问题
                        _latestError = "无法获取db中的流水号状态，编号:" + _serverNumber;
                        throw new Exception(_latestError);
                    }
                }
                catch (Exception ex)
                {
                    _latestError = ex.ToString();
                    if (exflag != null || _numberStatus == null)
                    {
                        throw ex;
                    }
                }

            }
            catch (Exception ex)
            {
                _serviceUseable = false;
            }
        }

        /// <summary>
        /// 获取当前服务器IP
        /// </summary>
        /// <returns></returns>
        static string GetIPAddress()
        {
            string str;
            string result = "";
            string hostName = Dns.GetHostName();
            IPAddress[] myIP = Dns.GetHostAddresses(hostName);
            foreach (IPAddress address in myIP)
            {
                str = address.ToString();
                for (int i = 0; i < str.Length; i++)
                {
                    if (str[i] >= '0' && str[i] <= '9' || str[i] == '.')
                        result = str;
                }
            }
            return result;
        }

        /// <summary>
        /// 最当前流水号状态里的最大值+1（LatestNumber+1）做为流水号组的最小值
        /// 最大值+100（LatestNumber+100），做为流水号组的最大值
        /// 将该值（LatestNumber+100）回写到LatestNumber.
        /// </summary>
        /// <param name="res">要处理的响应对象</param>
        public static void Generate(GeneratorResponse res)
        {
            if (_serviceUseable)
            {
                lock (_numberStatus)
                {
                    ResponseBody ris = new ResponseBody();

                    //服务器时间倒流!!
                    if (Convert.ToInt32(_numberStatus.Date) > Convert.ToInt32(DateTime.Now.ToString("yyMMddHH")))
                    {
                        _latestError = "服务器发现时间倒流，流水号生成服务拒绝运行！";
                        throw new Exception(_latestError);
                    }
                    else if (Convert.ToInt32(_numberStatus.Date) < Convert.ToInt32(DateTime.Now.ToString("yyMMddHH")))//下一时段
                    {
                        _numberStatus.LatestMaxNumber = 0;
                    }
                    int min = _numberStatus.LatestMaxNumber + 1;
                    _numberStatus.Date = DateTime.Now.ToString("yyMMddHH");
                    _numberStatus.LatestMaxNumber += 100;

                    Exception exflag = null;
                    try
                    {

                    }
                    catch (Exception ex)
                    {
                        if (exflag != null)
                        {
                            throw ex;
                        }
                    }

                    ris.ReferenceIDPrefix = _serverNumber + _numberStatus.Date;
                    ris.MinNumber = min;
                    ris.MaxNumber += _numberStatus.LatestMaxNumber;
                    res.HeadResultCode = 0;
                    res.ResponseBody = ris;
                }
            }
            else
            {
                throw new Exception("流水号生成服务暂不可用！" + _latestError);
            }
        }

    }
}
